package com.hex.ds.hdrs.watch.service;

import com.hex.ds.hdrs.agent.po.AgentConf;
import com.hex.ds.hdrs.agent.service.AgentConfService;
import com.hex.ds.hdrs.agent.service.AgentManager;
import com.hex.ds.hdrs.agent.service.AgentSession;
import com.hex.ds.hdrs.app.service.AppManager;
import com.hex.ds.hdrs.app.service.AppSession;
import com.hex.ds.hdrs.common.constant.Const;
import com.hex.ds.hdrs.common.utils.HdrsDateUtil;
import com.hex.ds.hdrs.common.utils.ListUtil;
import com.hex.ds.hdrs.engine.service.DispatcherService;
import com.hex.ds.hdrs.log.service.MailSendLogService;
import com.hex.ds.hdrs.log.service.SmsSendLogService;
import com.hex.ds.hdrs.period.job.po.HisBitch;
import com.hex.ds.hdrs.period.job.service.BackUpDataService;
import com.hex.ds.hdrs.period.task.po.PeriodTask;
import com.hex.ds.hdrs.period.task.po.PeriodTaskDef;
import com.hex.ds.hdrs.period.task.service.PeriodTaskDefService;
import com.hex.ds.hdrs.period.task.service.PeriodTaskService;
import com.hex.ds.hdrs.warn.po.WarnConf;
import com.hex.ds.hdrs.warn.service.WarnConfService;
import com.hex.ds.hdrs.warn.service.WarnSendMethodService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author lwz
 * @date 2021-02-26
 * @des
 */
@Slf4j
@Service
public class WatchService {

    @Autowired
    private MailSendLogService mailSendLogService;

    @Autowired
    private SmsSendLogService smsSendLogService;

    @Autowired
    private WarnConfService warnConfService;

    @Autowired
    private AgentConfService agentConfService;

    @Autowired
    private DispatcherService dispatcherService;

    @Autowired
    private AgentManager agentManager;

    @Autowired
    private AppManager appManager;

    @Autowired
    private WarnSendMethodService warnSendMethodService;

    @Autowired
    private PeriodTaskDefService periodTaskDefService;

    @Autowired
    private PeriodTaskService periodTaskService;

    @Autowired
    private BackUpDataService backUpDataService;


    public void agentLoginNotice(String agentCode) {
        AgentConf agentConf = this.agentConfService.qryAgentConfByAgentCode(agentCode);
        this.agentLoginNotice(agentConf);
    }

    /**
     * agent上线成功
     *
     * @param agentConf
     */
    public void agentLoginNotice(AgentConf agentConf) {
        try {
            List<WarnConf> warnConfList = warnConfService.getOffAgentInfo(Const.AGENT_WARN_ON_LINE, agentConf.getAgentCode());
            if (CollectionUtils.isNotEmpty(warnConfList)) {
                for (WarnConf warnConf : warnConfList) {
                    Map noticInfMap = warnConfService.getNoticInf(warnConf);
                    String subject = "Agent:" + agentConf.getAgentName() + "上线";
                    String content = this.getAgentOnContent(subject);
                    this.warnSendMethodService.add(noticInfMap, subject, content, null, warnConf.getPkId());
                }
            }
        } catch (Exception e) {
            log.error("【agentLoginNotice】异常: {}", e.getMessage(), e);

        }
    }

    private String getAgentOnContent(String subject) {
        StringBuffer sb = new StringBuffer();
        sb.append("尊敬的管理员，您好！").append("\r\n");
        sb.append("    " + subject + ",上线时间:" + HdrsDateUtil.getCurrentTime());
        return sb.toString();
    }

    /**
     * 中心切换成功
     *
     * @param centerName
     */
    public void centerSwitchNotic(String centerName) {
        try {
            List<WarnConf> warnConfList = warnConfService.selectWarnConfList(Const.CENTER_MASTER_SWITCH, true);
            for (WarnConf conf : warnConfList) {
                Map noticInfMap = this.warnConfService.getNoticInf(conf);
                String subject = "中心切换，最新Master节点为:" + centerName;
                String content = this.getCenterSwitchNoticContent(subject);
                this.warnSendMethodService.add(noticInfMap, subject, content, null, conf.getPkId());
            }
        } catch (Exception e) {
            log.error("【centerSwitchNotic】异常: {}", e.getMessage(), e);

        }
    }

    private String getCenterSwitchNoticContent(String subject) {
        StringBuffer sb = new StringBuffer();
        sb.append("尊敬的管理员，您好！").append("\r\n");
        sb.append("    " + subject + ",切换时间:" + HdrsDateUtil.getCurrentTime());
        return sb.toString();
    }


    /**
     * 任务执行完通知
     *
     * @param isCycleTask true 周期任务 false 定时任务
     * @param appCode
     * @param taskCode
     * @param taskName
     * @param isSuccess   true 执行成功 false 执行失败
     */
    public void taskFinishNotic(boolean isCycleTask, String appCode, String taskCode, String taskName, String date, boolean isSuccess) {
        try {
            String taskType = isCycleTask ? Const.IS_CYCLE_TASK : Const.IS_CRON_TASK;
            String taskStatus = isSuccess ? "执行成功" : "执行失败";

            List<WarnConf> warnConfList = this.warnConfService.getAppointTaskWarnList(appCode, Const.TASK_RUN_END_NOTIC, taskCode, taskType);
            if (CollectionUtils.isNotEmpty(warnConfList)) {
                for (WarnConf warnConf : warnConfList) {
                    List<String> taskCodeList = Arrays.asList(taskCode);
                    String jobCode = null;
                    List<PeriodTask> periodTaskList = this.periodTaskService.qryTaskByTaskCodes(warnConf.getAppCode(), date, taskCodeList);
                    if (!ListUtil.isEmpty(periodTaskList)) {
                        jobCode = periodTaskList.get(0).getJobCode();
                    }
                    Map noticInfMap = this.warnConfService.getNoticInf(warnConf);
                    String subject = "";
                    if (isCycleTask) {
                        subject = "任务:" + taskName + "   业务日期: " + date + "," + taskStatus;
                    } else {
                        subject = "任务:" + taskName + "   开始执行时间: " + date + "," + taskStatus;
                    }
                    String content = this.getTaskRunEndNoticContent(subject);
                    if (!isCycleTask) {
                        PeriodTaskDef def = this.periodTaskDefService.qryPeriodTaskDef(taskCode);
                        this.warnSendMethodService.add(noticInfMap, subject, content, null != def ? def.getJobCode() : null, warnConf.getPkId());
                    } else {
                        this.warnSendMethodService.add(noticInfMap, subject, content, jobCode, warnConf.getPkId());
                    }
                }

            }
        } catch (Exception e) {
            log.error("【taskFinishNotic】异常: {}", e.getMessage(), e);

        }
    }

    private String getTaskRunEndNoticContent(String subject) {
        StringBuffer sb = new StringBuffer();
        sb.append("尊敬的管理员，您好！").append("\r\n");
        sb.append("    " + subject);
        return sb.toString();
    }

    /**
     * @Method: againSessionResAndCurr <br>
     * @Param: [] <br>
     * @Return: void <br>
     * @Description：重新计算资源数和并发数c<br>
     * @Author： gc.zuo<br>
     * @Date： 2021/6/29 15:37 <br>
     * @Version： V1.0<br>
     */
    public void againSessionResAndCurr() {
        //分发器暂停
        log.info("分发器停用--开始");
        this.dispatcherService.stopDispatcher();
        log.info("分发器停用--结束");
        //App重新计算
        List<AppSession> appSessionList = appManager.getAppSessionList();
        appAgain(appSessionList);
        //Agent重新计算
        List<AgentSession> agentSessionList = agentManager.getAgentSessionList();
        agentAgain(agentSessionList);
        //分发器恢复
        log.info("分发器启用--开始");
        this.dispatcherService.continueDispatcher();
        log.info("分发器启用--结束");
    }

    /**
     * @Method: appAgain <br>
     * @Param: [appSessionList] <br>
     * @Return: void <br>
     * @Description：App重新计算<br>
     * @Author： gc.zuo<br>
     * @Date： 2021/6/30 13:56 <br>
     * @Version： V1.0<br>
     */
    public void appAgain(List<AppSession> appSessionList) {
        for (AppSession appSession : appSessionList) {
            //打标
            appSession.setMark(Const.APP_MARK_RUN);
            //重新计算资源数并发数并赋值
            appSession.againAppResAndCurr();
            //打标恢复
            appSession.setMark(Const.APP_MARK_STOP);
        }
    }

    /**
     * @Method: agentAgain <br>
     * @Param: [agentSessionList] <br>
     * @Return: void <br>
     * @Description：Agent重新计算<br>
     * @Author： gc.zuo<br>
     * @Date： 2021/6/30 13:57 <br>
     * @Version： V1.0<br>
     */
    public void agentAgain(List<AgentSession> agentSessionList) {
        for (AgentSession agentSession : agentSessionList) {
            //打标
            agentSession.setMark(Const.AGENT_MARK_RUN);
            //重新计算资源数并发数并赋值
            agentSession.againAgentResAndCurr();
            //打标恢复
            agentSession.setMark(Const.AGENT_MARK_STOP);
        }
    }

    /**
     * @Method: cleanTask <br>
     * @Param: [cleanDay] <br>
     * @Return: void <br>
     * @Description：清理历史任务<br>
     * @Author： gc.zuo<br>
     * @Date： 2022/8/16 10:11 <br>
     * @Version： V1.0<br>
     */
    public void cleanTask(String cleanDay) {
        try {
            String taskCrtTs = HdrsDateUtil.getAheadTime("1", Integer.valueOf(cleanDay) * 24, HdrsDateUtil.getCurTs());
            String date = HdrsDateUtil.dateDelay(HdrsDateUtil.getCurrentDate(), Integer.valueOf("-" + cleanDay));
            HisBitch cycleHisBitch = new HisBitch();
            cycleHisBitch.setDateTs(date);
            cycleHisBitch.setBitchType(Const.CYCLE);
            cycleHisBitch.setTaskCrtTs(taskCrtTs);
            backUpDataService.backUpData(cycleHisBitch);
        } catch (Exception e) {
            log.error("周期任务定时清理异常:{}", e.getMessage(), e);
        }
        try {
            String time = HdrsDateUtil.getAheadTime("1", Integer.valueOf(cleanDay) * 24, HdrsDateUtil.getCurTs());
            HisBitch cronHisBitch = new HisBitch();
            cronHisBitch.setDateTs(time);
            cronHisBitch.setBitchType(Const.CRON);
            backUpDataService.backUpData(cronHisBitch);
        } catch (Exception e) {
            log.error("定时任务定时清理异常:{}", e.getMessage(), e);
        }
    }

}
